package controller

import (
	"api/app/ctl/auto/v1/api"
	"api/app/ctl/auto/v1/mc"
	"api/app/ctl/models"
	"api/app/ctl/service"
	"api/config"
	"api/config/code"
	"api/libs/errs"
	"api/libs/orm"
	"fmt"
	"gitee.com/dreamwood/ez"
	"gitee.com/dreamwood/ez/server"
	"time"
)

type HeartBeatController struct {
	api.AppHostApi
}

func init() {

	c := &HeartBeatController{}
	c.RoutePrefix = ""
	c.AddRoute("/_heart_beat", c.HeartBeatAction)
	c.AddRoute("/_reg_service", c.RegServiceAction)
}

func (this *HeartBeatController) HeartBeatAction(operation *server.Operation) {
	op := this.TakeOver(operation)
	conf := new(config.ServiceConfig)
	e := operation.FillJson(conf)
	if op.CheckError(e) {
		return
	}
	if checkData(conf) {
		op.ReturnError(code.Error, "数据格式错误", "")
		return
	}
	crudHost := models.NewAppHostCrud()
	host, e := crudHost.FindOneBy(ez.M{"appId": conf.App.Id}, nil)
	if errs.Try(e) {
		errs.Get(e)
	}
	host.IsOn = true
	host.LastHeartBeatAt = ez.Now()

	host.State = 1
	host.StateInfo = fmt.Sprintf("心跳正常，上次心跳时间%s", ez.Now().Format(time.RFC3339))
	service.GetLock().Lock()
	defer service.GetLock().Unlock()

	host.Save()
	if op.CheckError(e) {
		return
	}
	op.ReturnSuccess("OK", host)
}
func (this *HeartBeatController) RegServiceAction(operation *server.Operation) {
	op := this.TakeOver(operation)
	conf := new(config.ServiceConfig)
	e := operation.FillJson(conf)
	if op.CheckError(e) {
		return
	}
	if checkData(conf) {
		op.ReturnError(code.Error, "数据格式错误", "")
		return
	}
	f := orm.NewFactory(mc.AppHostEzConfig)
	host := new(models.AppHost)
	e = f.FindOneBy(host, ez.M{"appId": conf.App.Id}, nil)
	if errs.Try(e) {
		errs.Get(e)
	}
	host.AppId = conf.App.Id
	host.Name = conf.App.Name

	host.LbName = conf.LoadBalance.Name
	host.LbWeight = conf.LoadBalance.Weight

	host.Host = conf.Host
	host.Port = conf.Port

	host.Starter = conf.RunPath
	host.Pid = conf.Pid

	host.IsOn = true
	host.LastHeartBeatAt = ez.Now()

	host.State = 1
	host.StateInfo = fmt.Sprintf("心跳正常，上次心跳时间%s", ez.Now().Format(time.RFC3339))
	service.GetLock().Lock()
	defer service.GetLock().Unlock()
	e = f.Update(host)
	if op.CheckError(e) {
		return
	}

	//注册路由信息
	rf := orm.NewFactory(mc.AppRouteEzConfig)
	for _, route := range conf.Routes {
		r := new(models.AppRoute)
		e = rf.FindOneBy(r, ez.M{"appId": conf.App.Id, "from": route.From, "to": route.To, "sort": route.Sort}, nil)
		if errs.Try(e) {
			errs.Get(e)
		}
		r.AppId = conf.App.Id
		r.Name = conf.App.Name
		r.From = route.From
		r.To = route.To
		r.IsOn = true
		r.Sort = route.Sort
		r.Port = route.Port
		e = rf.Update(r)
		if op.CheckError(e) {
			return
		}
	}

	go func() {
		//操作完成后更新网关数据
		ez.Debug("开始准备GateWay主机数据")
		service.PrepareHost()
		ez.Debug("开始准备GateWay路由转发数据")
		service.PrepareRoute()
	}()

	op.ReturnSuccess("OK", host)
}

func checkData(conf *config.ServiceConfig) bool {
	if conf.App.Id == "" {
		return true
	}
	if conf.App.Name == "" {
		return true
	}
	if conf.Port == "" {
		return true
	}
	if conf.Host == "" {
		return true
	}
	if conf.Routes == nil {
		return true
	}
	return false
}
